#include "DebugRenderer.h"

#include "Game.h"
#include "Renderer.h"

DebugRenderer::DebugRenderer() {
	this->physicsSDK = NULL;
	this->scene = NULL;
	this->debugRenderable = NULL;
	this->enabled = false;
}

DebugRenderer::~DebugRenderer() {

}

void DebugRenderer::Init(NxPhysicsSDK *physicsSDK, NxScene* scene) {
	this->physicsSDK = physicsSDK;
	this->scene = scene;
}

void DebugRenderer::SetParameterEnabled(NxParameter visualizeParam, bool enabled) {
	if(physicsSDK == NULL) {
		PrintError();
		return;
	}
	physicsSDK->setParameter(visualizeParam, enabled ? 1.0f : 0.0f);
}

bool DebugRenderer::GetParameterEnabled(NxParameter visualizeParam) {
	return physicsSDK->getParameter(visualizeParam) != 0.0f;
}

void DebugRenderer::SetScale(float scale) {
	if(physicsSDK == NULL) {
		PrintError();
		return;
	}
	physicsSDK->setParameter(NX_VISUALIZATION_SCALE, scale);
}

void DebugRenderer::SetupColor(NxU32 color) {
	NxF32 b = NxF32((color)&0xff)/255.0f;
	NxF32 g = NxF32((color>>8)&0xff)/255.0f;        
	NxF32 r = NxF32((color>>16)&0xff)/255.0f;
	SurfaceRenderingData srd;
	srd.SetColor(r, g, b, 1.0f);
	Renderer::SetMaterial(srd);
}

void DebugRenderer::Update(NxScene* scene) {
	if(enabled) {
		this->debugRenderable = (NxDebugRenderable*)(scene->getDebugRenderable());
	}
}

void DebugRenderer::Draw() {
	if(debugRenderable == NULL || !enabled) {
		return;
	}

	glDisable(GL_LIGHTING);

	glLineWidth(2.0f);

	// Render points       
	glPushMatrix();
	{            
		NxU32 nbPoints = debugRenderable->getNbPoints();            
		const NxDebugPoint* points = debugRenderable->getPoints();
		glBegin(GL_POINTS);
		while(nbPoints--)
		{                
			SetupColor(points->color);                
			glVertex3fv(&points->p.x);                
			points++;
		}            
		glEnd();        
	}   
	glPopMatrix();

	// Render lines  
	glPushMatrix();
	{           
		NxU32 nbLines = debugRenderable->getNbLines();            
		const NxDebugLine* lines = debugRenderable->getLines();            
		glBegin(GL_LINES);            
		while(nbLines--)
		{                
			SetupColor(lines->color);                
			glVertex3fv(&lines->p0.x);
			glVertex3fv(&lines->p1.x);                
			lines++;            
		}            
		glEnd();        
	}    
	glPopMatrix();
	
	// Render triangles     
	glPushMatrix();
	{            
		NxU32 nbTris = debugRenderable->getNbTriangles();            
		const NxDebugTriangle* triangles = debugRenderable->getTriangles();            
		glBegin(GL_TRIANGLES);            
		while(nbTris--)            
		{                
			SetupColor(triangles->color);                
			glVertex3fv(&triangles->p0.x);                
			glVertex3fv(&triangles->p1.x);                
			glVertex3fv(&triangles->p2.x);                
			triangles++;            
		}            
		glEnd();        
	}    
	glPopMatrix();

	glEnable(GL_LIGHTING);
}

void DebugRenderer::PrintError() {
	Game::log.LogError("DebugRenderer: call Init before use.");
}

